package cn.fcj.f20240328.fsocket.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

import cn.fcj.f20240328.fsocket.base.FBaseNIOSocket;
/**
 * @项目名称:FSocket
 * @功能描述:socket客户端实现
 * @开发　者:mochhk
 * @邮　　箱:mochhk@163.com
 * @CreateDate:2024/4/5 13:05
 */
public class FNIOSocketClient extends FBaseNIOSocket<SocketChannel> {
    @Override
    public void initSocket() throws IOException {
        System.out.println("----------socket正在启动......ip:" + ip + "----port:" + port);
        //1)开启多路复用器
        mSelector = Selector.open();
        //2) 开启服务通道
        mChannel = SocketChannel.open();
        //3)设置为非阻塞
        mChannel.configureBlocking(false);
        //4)绑定端口
        mChannel.connect(new InetSocketAddress(ip, port));
        //5)注册,标记服务通标状态
        mChannel.register(mSelector, SelectionKey.OP_CONNECT);
        System.out.println("------------socket启动完毕----------------");
    }

    @Override
    public void connectionHandler(SelectionKey key) throws IOException{
        if (key.isConnectable()) {
            SocketChannel channel=(SocketChannel)key.channel();
            while (!channel.finishConnect()) {

            }
            //会被select()阻塞掉的
            channel.register(mSelector, SelectionKey.OP_READ);
            mSelector.wakeup();
            System.out.println("------------socket------运行中------连接成功----");
        }
        super.connectionHandler(key);
    }

    @Override
    public void exceptionHandler(Exception e, ErrorCode errorCode, SelectionKey key) {
        super.exceptionHandler(e, errorCode, key);
        if(errorCode==ErrorCode.SOCKET_DISCONNECT){
            if(key!=null)
                key.cancel();
            closeSelectorAndChannl();
        }
    }
}
